#include "ModRunFactoryAbstract.h"
#include <QDebug>

#include "../Output/FactoryOutput.h"

#include "Gof23/Gof_Factory/FactoryAbstract/FactoryProductA.h"
#include "Gof23/Gof_Factory/FactoryAbstract/FactoryProductB.h"
#include "Gof23//Gof_Factory/FactoryMethod/FactoryByd.h"
#include "Gof23//Gof_Factory/FactoryMethod/FactoryBMW.h"
#include "Gof23//Gof_Factory/FactoryMethod/FactoryAudi.h"

//抽象工厂模式的ModRun（Abstract Factory）
ModRunFactoryAbstract::ModRunFactoryAbstract()
{
    //模式名称;
    m_strModelName = "抽象工厂模式（Abstract Factory）;";
    //模式描述;
    m_strModelDesc = "抽象工厂模式:\r\n"
        "抽象工厂模式提供创建一系列相关或相互依赖对象的接口，而无需指定它们具体的类。\r\n"
        "当存在多个产品系列，而客户端只使用一个系列的产品时，可以考虑使用抽象工厂模式。\r\n"
        "缺点：当增加一个新系列的产品时，不仅需要现实具体的产品类，还需要增加一个新的创建接口，扩展相对困难。\r\n"
        ;
}

//初始化显示模式;
void ModRunFactoryAbstract::InitDisplay()
{
    qDebug() << m_strModelName;
    std::shared_ptr<IOutput> pOutPut = FactoryOutput::GetInstance()->CreateDescOutput();
    if (pOutPut)
    {
        std::initializer_list<QString> outList{ m_strModelName,m_strModelDesc};
        pOutPut->OutPut(outList);
    }
}

//返回模式类型;
EnumModRun ModRunFactoryAbstract::GetEnum()
{
    return emModRunFactoryAbstract;
}

//运行模式;
void ModRunFactoryAbstract::ModRun()
{
    std::shared_ptr<IOutput> pOutPut = FactoryOutput::GetInstance()->CreateRunOutput();
    if (pOutPut)
    {
        std::initializer_list<QString> outListStart{ "========" + m_strModelName + " start:======= " };
        std::initializer_list<QString> outListEnd{ "========" + m_strModelName + "end:======= " };
        pOutPut->OutPut(outListStart);

        //抽象工厂;
        FactoryProductA productA;
        FactoryProductB productB;
        std::initializer_list<QString> outListStartA{ "======== 工厂A产品族 start:======= " };
        pOutPut->OutPut(outListStartA);

        std::unique_ptr<InterfaceCar> carA(productA.CreateCar());
        if (carA)
        {
            carA->Run();
        }

        std::unique_ptr<InterfaceRocket> rocketA(productA.CreateRocket());
        if (rocketA)
        {
            rocketA->Fly();
        }

        std::unique_ptr<InterfaceScreen> screenA(productA.CreateScreen());
        if (screenA)
        {
            screenA->Display();
        }

        std::initializer_list<QString> outListStartB{ "======== 工厂B产品族 start:======= " };
        pOutPut->OutPut(outListStartB);

        std::unique_ptr<InterfaceCar> carB(productB.CreateCar());
        if (carB)
        {
            carB->Run();
        }

        std::unique_ptr<InterfaceRocket> rocketB(productB.CreateRocket());
        if (rocketB)
        {
            rocketB->Fly();
        }

        std::unique_ptr<InterfaceScreen> screenB(productB.CreateScreen());
        if (screenB)
        {
            screenB->Display();
        }

        pOutPut->OutPut(outListEnd);
    }

}

InterFaceModRun* ModRunFactoryAbstract::CreateMe()
{
    return new ModRunFactoryAbstract();
}
